//自己
class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        int n = s.size(), len=0;
        unordered_set<char> hash;
        for (int left=0, right=0; right < n; right++)//进窗口;  right越界之后, 即使left再移动得到的len也不是最大值了
        {
            auto ret = hash.insert(s[right]);//进窗口 同时判断有没有重复
            //有重复, 出窗口(left跳到重复元素后)
            if (ret.second == false)
            {
                while (s[left] != s[right]) //s[right]指重复元素的前一个
                {
                    hash.erase(s[left]);
                    ++left;
                }
                //重复的这个元素在hash表中不能删除, 因为重复元素(后一个)需要进入表中
                ++left;//跳到重复元素后
            }
            else //true
            {
                len = max(len, right-left+1);//更新len
                cout << left << right << len << endl;
            }
        }
        return len;//hash.size()表示的只是最后一个不重复字符串的长度
    }
};


//答案
class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        int n = s.size(), len=0, left=0, right=0, hash[128] = {0};//模拟哈希表(unorder_map),  ASCII一共有128个码
        while (right < n)               //right越界之后, 若left再移动得到的len就不是较大值了, 所以直接结束
        {
            hash[s[right]]++;//1. 进窗口 
            while (hash[s[right]] > 1) //2. 判断有没有重复
                hash[s[left++]]--; //3. 出窗口(left跳到重复元素后)
            len = max(len, right-left+1);//4. 更新len
            right++;//下一个元素
        }
        return len;
    }
};
//时间 O(N)
//空间 O(128)->O(1)